#!/usr/bin/env python
#
#

__author__ = "Zhengfa DANG"

from OAuth import live

from webapp2 import uri_for
from google.appengine.ext import webapp
from google.appengine.ext.webapp import util
from google.appengine.api import memcache
import logging
from utilities import dump, render_template 
import random
import datetime

# skydrive client
application_key = "00000000440D2D6B" 
application_secret = "DauLJSGmlaztmU68NfU4bRWVPWx04UME"  
#callback_url = "http://skyalbum.zfdang.com:8080/live/verify"
callback_url = "http://skyalbum.zfdang.com/live/verify"

client = live.SkyDriveClient(application_key, application_secret, callback_url)

# three methods to operate access_token by userid
def memcache_get_access_token(userid):
    access_token = memcache.get("%s_access_token"%(userid))
    return access_token

def memcache_set_access_token(userid, access_token, expiration):
    memcache.add("%s_access_token"%(userid), access_token, expiration)
    return

def memcache_delete_access_token(userid):
    memcache.delete("%s_access_token"%(userid))

# check access token for 
def check_access_token(handler):
    # check userid from cookis, and find access_token in memcache
    # then update client.userid, client.access_token
    userid = handler.request.cookies.get("userid")
    if userid is None:
        userid = str(random.randint(1000000000000,9000000000000))
        handler.response.set_cookie("userid", userid, expires=datetime.datetime.now()+datetime.timedelta(days=60), 
                                    path="/", domain='zfdang.com', secure=False)
        client.userid = userid
        client.access_token = None
        client.append_http_logs("check_access_token: new userid = %s" %(userid))
    else:
        client.userid = userid
        access_token = memcache_get_access_token(userid)
        client.access_token = access_token
        client.append_http_logs("check_access_token: existed userid = %s, access_token = %s" %(userid, access_token))

    # save to client instance
    return (client.userid, client.access_token)

# decorator for handler
def check_login(func):
    def call(*args, **kwargs):
        # get userid from cookie
        logging.info("check_login: ")
        
        (userid, access_token) = check_access_token(args[0])
        if access_token == None:
            logging.info("check_login: @ %s.%s : failed" %(func.__module__, func.func_name))
            logging.info("check_login: redirect to %s" %(uri_for("live")))
            args[0].redirect(uri_for("live"))
        else:
            logging.info("check_login @ %s.%s : success" %(func.__module__, func.func_name))
            client.access_token = access_token
            return func(*args, **kwargs)
    return call


class LiveHandler(webapp.RequestHandler):

  def get(self, mode=""):
    # show 
    (userid, access_token) = check_access_token(self)
    
    if mode == "login":
        # this will redirect to live.com for authorization
        # it will redirect to client.callback_url with ?code=xxxxx
        _url = client.get_authorization_code_url()
        client.append_http_logs("Start OAuth, redirect to url = %s" %(_url))
        self.redirect(_url)

    if mode == "verify":
        # callback from live.com, with ?code=XXXX, use this code to get access_token
        access_code = self.request.get("code")

        client.append_http_logs("Receive callback from OAuth: access_code = %s" %(access_code))

        # get access_token with access_code
        client.append_http_logs("Init call to get access token ...")
        client.get_authorization_token(access_code)
        if client.is_logined():
            memcache_set_access_token(userid, client.access_token, client.access_token_expire_in)
            client.append_http_logs("Get access token: %s = " %(client.access_token))
        
        logging.info("LiveHandler: verify: redirect to %s"%(uri_for("live")))
        self.redirect("%s" %(uri_for("live")))
      

    if mode == "userinfo":
        if not client.is_logined():
            self.redirect(uri_for("live"))

        # show live.com account
        userinfo = client.lookup_user_info()
        template_values = {
                    'userinfo': userinfo,
                    'home_url': uri_for("live"),
        }
        return self.response.out.write(render_template("skydrive/userinfo.html", template_values, client))

    if mode == "reset":
        memcache_delete_access_token(userid)
        client.clear_http_logs()
        client.access_token = None
        self.redirect(uri_for("live"))
    
    # rendering the default page
    template_values = {
                'is_login': (client.access_token and "Yes") or "No", 
                'home_url': uri_for("live"),
                "skydrive_url": uri_for("skydrive"),
    }
    logging.info("MainHandler: rendering the default page, is_loing = {%s}" % (template_values['is_login']))
    self.response.out.write(render_template("skydrive/index.html", template_values, client))


class SkyDriveHandler(webapp.RequestHandler):

  @check_login
  def get(self):
    logging.info("SkyDriveHandler: get")
    contents = client.list_skydrive()
    template_values = {
                'contents': contents,
                'home_url': uri_for("skydrive"),
    }
    return self.response.out.write(render_template("skydrive/list_folder.html", template_values, client))

class SkyDriveFolderHandler(webapp.RequestHandler):

  @check_login
  def get(self, folder=""):
    # show 
    logging.info("SkyDriveFolderHandler: get: folder = %s"%(folder))
    (parent_id, contents) = client.list_folder(folder)
    template_values = {
                'is_login': client.is_logined(),
                'contents': contents,
                'home_url': uri_for("skydrive"),
                "parent_id": parent_id,
    }
    return self.response.out.write(render_template("skydrive/list_folder.html", template_values, client))


class SkyDriveFileHandler(webapp.RequestHandler):
  @check_login
  def get(self, file=""):
    # show 
    logging.info("SkyDriveFileHandler: get: file = %s" %(file))
    (content_type, content_data) = client.get_file(file)
    self.response.headers['Content-Type'] = content_type
    self.response.out.write('%s' %(content_data))


